#pragma once

#include <vector>

namespace alpha { namespace utility {

template <typename K, typename T, typename Container = std::vector<std::pair<K, T> > >
class simple_map
{
public:
	typedef typename Container::allocator_type allocator_type;
	typedef typename Container::const_iterator const_iterator;
	typedef typename Container::const_pointer const_pointer;
	typedef typename Container::const_reference const_reference;
	typedef typename Container::const_reverse_iterator const_reverse_iterator;
	typedef typename Container::difference_type difference_type;
	typedef typename Container::iterator iterator;
	typedef K key_type;
	typedef T mapped_type;
	typedef typename Container::pointer pointer;
	typedef typename Container::reference reference;
	typedef typename Container::reverse_iterator reverse_iterator;
	typedef typename Container::size_type size_type;
	typedef typename Container::value_type value_type;

	const_iterator begin() const { return container_.begin(); }
	iterator begin() { return container_.end(); }

	const_iterator end() const { return container_.end(); }
	iterator end() { return container_.end(); }

	const_reverse_iterator rbegin() const { return container_.rbegin(); }
	reverse_iterator rbegin() { return container_.rbegin(); }

	const_reverse_iterator rend() const { return container_.rend(); } 
	reverse_iterator rend() { return container_.rend(); }

	iterator find(const K& key)
	{
		iterator i = container_.begin();
		for (; i != container_.end(); ++i)
			if (i->first == key)
				break;
		return i;
	}
	const_iterator find(const K& key) const
	{
		const_iterator i = container_.begin();
		for (; i != container_.end(); ++i)
			if (i->first == key)
				break;
		return i;
	}

	size_type count(const K& key) const { return find(key) == end()? 0: 1; }

	allocator_type get_allocator() const { return container_.get_allocator(); }

	T& operator[](const K& key)
	{
		iterator i = find(key);
		if (i == end())
		{
			container_.push_back(value_type(key, T()));
			i = container_.end();
			--i;
		}
		return i->second;
	}
	
	void clear() { container_.clear(); }

	std::pair<iterator, bool> insert(const value_type& val)
	{
		const_iterator i = find(val.first);
		if (i != end())
			return std::pair<iterator, bool>(i, false);
		container_.push_back(val);
		i = container_.end();
		--i;
		return std::pair<iterator, bool>(i, true);		
	}
	template<class InputIterator>
	void insert(InputIterator first, InputIterator last)
	{
		for (InputIterator i = first; i != last; ++i)
			insert(*i);
	}

	iterator erase(iterator where) { return container_.erase(where); }
	iterator erase(iterator first, iterator last) { return container_.erase(first, last); }
	size_type erase(const key_type& key)
	{
		iterator i = find(key);
		if (i == end())
			return 0;
		erase(i);
		return 1;
	}
	
	size_type max_size() const { return container_.max_size(); }

	size_type size() const { return container_.size(); }

	void swap(simple_map& r) { return container_.swap(r.container_); }

private:
		Container container_;
};

}} //namespace alpha::utility
